/*
package com.ruoyi.plc;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.ObjectUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.order.domain.*;
import com.ruoyi.order.enums.NodeResultStatusEnum;
import com.ruoyi.order.enums.NodeTestResultEnum;
import com.ruoyi.order.event.ProcessDataEvent;
import com.ruoyi.order.proxy.factory.req.FactoryHeader;
import com.ruoyi.order.proxy.factory.req.ProcessDataRequest;
import com.ruoyi.order.service.IMesDetectNodeService;
import com.ruoyi.order.service.IMesModelNodeRelaService;
import com.ruoyi.order.service.IMesProdRecordService;
import com.ruoyi.order.service.IMesProductNodeResultService;
import com.ruoyi.order.station.handle.StationExchangeService;
import com.ruoyi.order.station.request.*;
import com.ruoyi.order.station.cmd.DB5409;
import com.ruoyi.order.station.response.DB5410Server;
import com.ruoyi.order.station.response.PassResponse;
import com.ruoyi.order.station.transform.DBTrans;
import com.ruoyi.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
@Component("plcJob")
public class PLCJob {

    @Autowired
    private StationExchangeService stationExchangeService;
    @Autowired
    private IMesProdRecordService prodRecordService;
    @Autowired
    private IMesModelNodeRelaService mesModelNodeRelaService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IMesDetectNodeService detectNodeService;
    @Autowired
    private IMesProductNodeResultService productNodeResultService;

    private final ApplicationEventPublisher eventPublisher;
    private static Map<String, List<MesModelNodeRela>> partModelRelaMap = new HashMap<>();

    private static Set<String> operationNodeCodeSet = new HashSet<>();
    static {
        operationNodeCodeSet.add("7");
        operationNodeCodeSet.add("9");
        operationNodeCodeSet.add("11");
        operationNodeCodeSet.add("12");
        operationNodeCodeSet.add("19");
        operationNodeCodeSet.add("21");
        operationNodeCodeSet.add("23");
    }

    public PLCJob(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void plcRW(String lineNumber,String nodeCode) {
        if (lineNumber != null && lineNumber.equals("1")) {
            lineOne(lineNumber, nodeCode);
        }
    }

    private void lineOne(String lineNumber,String nodeCode) {
        log.info("组装线定时任务 lineNumber={},nodeCode={}", lineNumber, nodeCode);
        MesDetectNode mesDetectNode = new MesDetectNode();
        mesDetectNode.setSubsysCode(lineNumber);
        List<MesDetectNode> detectNodeList = detectNodeService.selectMesDetectNodeList(mesDetectNode);
        for (MesDetectNode detectNode : detectNodeList) {
            //单独测试nodeCode站位
            if (StringUtils.isNotEmpty(nodeCode)&&!detectNode.getNodeCode().equals(nodeCode)) {
                continue;
            }
            //读取DB5409
            DB5409 db5409 = stationExchangeService.getDB5409(detectNode);
            //首站处理
            if (detectNode.getSortIndex() == 1) {
                log.info("handleFirstStation is Start!, detectNode.getNodeCode=()",detectNode.getNodeCode());
                handleFirstStation(lineNumber, db5409, detectNode);
                log.info("handleFirstStation is End!");
            } else if (detectNode.getSortIndex() > 1 && detectNode.getSortIndex() < detectNodeList.size()) {
                //执行中间过站
                log.info("handleMiddleStation is Start! detectNode.getNodeCode=()",detectNode.getNodeCode());
                handleMiddleStation(lineNumber, db5409, detectNode);
                log.info("handleMiddleStation is End!");
            } else if (detectNode.getSortIndex() == detectNodeList.size() && detectNode.getSortIndex() >= 1) {
                //执行尾站
                log.info("handleLastStation is Start! detectNode.getNodeCode=()",detectNode.getNodeCode());
                handleLastStation(lineNumber, db5409, detectNode);
                log.info("handleLastStation is End!");
            }
        }
    }

    */
/**
     * 生产数据处理
     *
     * @param detectNode
     * @param isFirstStation 是否是首站
     *//*

    public boolean handleProductData(MesDetectNode detectNode, boolean isFirstStation) {
        //生产数据已生成
            //生产数据读取
            ProcessRequest processRequest = stationExchangeService.readProductHeader(detectNode, isFirstStation);
            String partNumber = "";
            try {
                partNumber = new String(processRequest.getPartIdentifier(), "UTF-8");
                partNumber = partNumber.trim();
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            if (StringUtils.isEmpty(partNumber)){
                log.error("processRequest.getPartIdentifier()={},获取到的产品码为空 ", partNumber);
                return false;
            }
            //查询是否已做过数据
            MesProductNodeResult existResult = productNodeResultService.getByStationCodeAndPartNumber(detectNode.getNodeCode(), partNumber);
            if (existResult != null){
                return true;
            }
            MesProductNodeResult productNodeResult = new MesProductNodeResult();
            String testDetail = "";
            if (detectNode.getNodeCode().equals("1") || detectNode.getNodeCode().equals("9")
                    || detectNode.getNodeCode().equals("12")
                    || detectNode.getNodeCode().equals("17")
                    || detectNode.getNodeCode().equals("19")
                    || detectNode.getNodeCode().equals("21")) {
                Object object1 = stationExchangeService.readProductData(detectNode, isFirstStation);
                Object object2 = stationExchangeService.readProductDataExtended(detectNode);
                testDetail = ObjectUtils.mergeObj2JSONStr(object1, object2);
                log.info("handleProductData object = {}", testDetail);
            } else {
                Object object = stationExchangeService.readProductData(detectNode, isFirstStation);
                testDetail = ObjectUtils.obj2JSONStr(object);
                log.info("handleProductData object = {}", testDetail);
            }
            productNodeResult.setTestHeader(JSON.toJSONString(DBTrans.getProductHeader(processRequest)));
            productNodeResult.setTestDetail(testDetail);
            productNodeResult.setSubsysCode(detectNode.getSubsysCode());
            productNodeResult.setIp(detectNode.getIp());
            productNodeResult.setMachineModel(detectNode.getMachineModel());
            productNodeResult.setSortIndex(detectNode.getSortIndex());
            productNodeResult.setStationCode(detectNode.getNodeCode());
            productNodeResult.setStatus(NodeResultStatusEnum.VALID.getCode());
            productNodeResult.setPartNumber(partNumber);
            productNodeResult.setTestResult(String.valueOf(processRequest.getResult()));
            productNodeResultService.insertMesProductNodeResult(productNodeResult);
            //读生产数据完成后写入DB5439
            stationExchangeService.wirteProductDataResponse(DBTrans.getDB5439Server(processRequest), detectNode, isFirstStation);
            //发送事件，发送数据给工厂
            eventPublisher.publishEvent(new ProcessDataEvent(this, transformProcessData(processRequest,productNodeResult.getId(), testDetail)));
            return true;
    }

    */
/**
     * 转换成工厂数据格式
     *
     * @param processRequest
     * @param resultId 生产记录ID
     * @param body
     * @return
     *//*

    public ProcessDataRequest transformProcessData(ProcessRequest processRequest,Long resultId, String body) {
        ProcessDataRequest processDataRequest = new ProcessDataRequest();
        FactoryHeader header = new FactoryHeader();
        header.setResultId(resultId);
        header.setLineNo(processRequest.getLineNo());
        if(processRequest.getStationNo()<10){
            header.setStationNo("OP0" + processRequest.getStationNo());
        }else {
            header.setStationNo("OP" + processRequest.getStationNo());
        }
        header.setStationIndex(processRequest.getStationindex());
        header.setWpcId(new String(processRequest.getWpcId()));
        header.setWpcId(StringUtils.trim(header.getWpcId()));
        header.setTypeNo(new String(processRequest.getTypeNo()));
        header.setTypeNo(StringUtils.trim(header.getTypeNo()));
        header.setPartIdentifier(new String(processRequest.getPartIdentifier()));
        header.setPartIdentifier(StringUtils.trim(header.getPartIdentifier()));
        header.setProductionTime(new String(processRequest.getProductionTime()));
        header.setProductionTime(header.getProductionTime().trim());
        header.setResult(processRequest.getResult());
        header.setNoBits(processRequest.getNoBits());
        processDataRequest.setHeader(header);
        processDataRequest.setBody(body);
        return processDataRequest;
    }

    */
/**
     * 首站处理
     *
     * @param db5409
     * @param detectNode
     *//*

    public void handleFirstStation(String lineNumber, DB5409 db5409, MesDetectNode detectNode) {
        if (db5409.getT10Send() == 1) {
            //首站，1: PLC可以读DB5410 数据块
            DB5410PLC db5410PLC = stationExchangeService.getDB5410(detectNode);
            MesProdRecord mesProdRecord = new MesProdRecord();
            try {
                mesProdRecord.setModelCode(new String(db5410PLC.getRouteList(), "UTF-8"));
                mesProdRecord.setPartId(new String(db5410PLC.getPartIdentifier(), "UTF-8"));
                mesProdRecord.setPartId(StringUtils.trim(mesProdRecord.getPartId()));
                mesProdRecord.setModelCode(StringUtils.trim(mesProdRecord.getModelCode()));
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
            if (StringUtils.isEmpty(mesProdRecord.getPartId())){
                log.error("db5410PLC.getPartIdentifier()={},获取到的产品码为空 ", mesProdRecord.getPartId());
                db5409.setT10Result(2);
                stationExchangeService.writeDB5409(db5409, detectNode);
                return;
            }
            //保存入库
            if (Objects.isNull(prodRecordService.getMesProdRecordByPartId(mesProdRecord.getPartId()))) {
                log.info("保存入库 mesProdRecord = {}", JSONObject.toJSONString(mesProdRecord));
                prodRecordService.insertMesProdRecord(mesProdRecord);
            }
            //获取产品所有必生产站位列表
            List<MesModelNodeRela> relaList = queryRelaListByPartId(lineNumber,mesProdRecord.getPartId());
            //写入DB5409
            log.info("写入DB5409");
            if (CollectionUtils.isNotEmpty(relaList)) {
                db5409.setT10Result(1);
            } else {
                db5409.setT10Result(2);
                log.error("db5410PLC.getRouteList()={},获取到的必过站位列表为空 ", db5410PLC.getRouteList());
            }
            stationExchangeService.writeDB5409(db5409, detectNode);
            //写入DB5410 Server
            log.info("写入DB5410 Server detectNode.getNodeCode() ={}", detectNode.getNodeCode());
            DB5410Server db5410Server = DBTrans.getDB5410Server(db5410PLC);
            stationExchangeService.wirteDB5410Server(db5410Server, detectNode);
        }
        //首站生产已完成，读取生产数据
        if (db5409.getT30SendFirst() == 1) {
            boolean dataResult = handleProductData(detectNode, true);
            if (dataResult) {
                db5409.setT30ResultFirst(1);
            }else {
                db5409.setT30ResultFirst(2);
            }
            stationExchangeService.writeDB5409(db5409, detectNode);
        }
    }

    */
/**
     * 中间站处理
     *
     * @param db5409
     * @param detectNode
     *//*

    public void handleMiddleStation(String lineNumber, DB5409 db5409, MesDetectNode detectNode) {
        //非首站，1: PLC已扫码partNumber，可以读DB5411数据块
        if (db5409.getT11Send() == 1) {
            passStation(lineNumber, db5409, detectNode);
        }
        //生产数据已完成，进行读取，并写入已完成读取标记
        if (db5409.getT30Send() == 1) {
            boolean dataResult = handleProductData(detectNode,false);
            if (dataResult) {
                db5409.setT30Result(1);
            }else {
                db5409.setT30Result(2);
            }
            stationExchangeService.writeDB5409(db5409, detectNode);
        }
    }

    */
/**
     * 尾站处理
     *
     * @param db5409
     * @param detectNode
     *//*

    public void handleLastStation(String lineNumber, DB5409 db5409, MesDetectNode detectNode) {
        //非首站，1: PLC已扫码partNumber，可以读DB5411数据块
        if (db5409.getT11Send() == 1) {
            passStation(lineNumber, db5409, detectNode);
        }
        //检测关键节点的QunlityGate信息
        if (db5409.getT16Send() == 1) {
            //所有节点生产信息获取
            DB5416PLC db5416PLC = stationExchangeService.getDB5416(detectNode);
            //写入指令数据
            db5409.setT16Result(1);
            stationExchangeService.writeDB5409(db5409, detectNode);

            //写入db5416响应报文
            stationExchangeService.writeDB5416(db5416PLC, detectNode);

        }

        //生产数据已完成，进行读取，并写入已完成读取标记
        if (db5409.getT30Send() == 1) {
            if (handleProductData(detectNode, false)) {
                db5409.setT30Result(1);
            }else{
                db5409.setT30Result(2);
            }
            stationExchangeService.writeDB5409(db5409, detectNode);
        }
        if (db5409.getT19Send() == 1){
            //产品下线，插入产品表
            DB5419PLC db5419PLC = stationExchangeService.getDB5419(detectNode);
            log.info("db5419PLC = {}", JSON.toJSONString(db5419PLC));
            //写入指令数据
            db5409.setT19Result(1);
            stationExchangeService.writeDB5409(db5409, detectNode);
            //写入db5416响应报文
            stationExchangeService.writeDB5419(db5419PLC, detectNode);

        }
    }

    */
/**
     * 过站处理,中间和尾站共用逻辑
     *
     * @param db5409
     * @param detectNode
     *//*

    public void passStation(String lineNumber, DB5409 db5409, MesDetectNode detectNode) {
        //当前站点是否生产标记
        boolean isProduce = false;
        //当前需要生产站位编码
        String currentStationCode = "";
        //必要生产站位编码列表
        List<String> needStationCodeList = new ArrayList<>();
        //已生产历史记录
        Map<String, String> produceRecordMap = new HashMap<>();
        String partId = "";
        PassRequest passRequest = stationExchangeService.getPassRequest(detectNode);
        try {
            partId = new String(passRequest.getPartIdentifier(), "UTF-8");
            partId = partId.trim();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        if ("EMPTY00000".equals(partId)||StringUtils.isEmpty(partId)){
            //写入过站结果
            PassResponse passResponse = new PassResponse();
            passResponse.setLineNo(passRequest.getLineNo());
            passResponse.setTelegramNo(passRequest.getTelegramNo());
            passResponse.setStationNo(passRequest.getStationNo());
            passResponse.setStationindex(passRequest.getStationindex());
            passResponse.setPartIdentifier(passRequest.getPartIdentifier());
            passResponse.setTypeNo(passRequest.getTypeNo());
            passResponse.setReturnCode(2);
            //写入过站数据，DB511块
            stationExchangeService.writePassResponse(passResponse, detectNode);
            //写入指令数据
            db5409.setT11Result(2);
            stationExchangeService.writeDB5409(db5409, detectNode);
            return;
        }
        //获取产品所有必生产站位列表
        List<MesModelNodeRela> relaList = queryRelaListByPartId(lineNumber, partId);
        if (CollectionUtils.isEmpty(relaList)){
            //写入指令数据
            db5409.setT11Result(2);
            stationExchangeService.writeDB5409(db5409, detectNode);
            return;
        }
        for (MesModelNodeRela rela : relaList) {
            if (rela.getStationCode().indexOf("_") > 0) {//25站位有两个，去掉下标索引，直接用25号站代替
                needStationCodeList.add(rela.getStationCode().split("_")[0]);
            } else {
                needStationCodeList.add(rela.getStationCode());
            }
        }
        //获取生产数据入库记录
        MesProductNodeResult param = new MesProductNodeResult();
        param.setSubsysCode(detectNode.getSubsysCode());
        param.setPartNumber(partId);
        param.setStatus(NodeResultStatusEnum.VALID.getCode());
        List<MesProductNodeResult> nodeResultList = productNodeResultService.selectMesProductNodeResultByPartNumber(param);
        if (CollectionUtils.isNotEmpty(nodeResultList)) {
            for (MesProductNodeResult result : nodeResultList) {
                if (result.getStationCode().indexOf("_") > 0) {//25站位有两个，去掉下标索引，直接用25号站代替
                    produceRecordMap.put(result.getStationCode().split("_")[0], result.getStationCode().split("_")[0]);
                } else {
                    produceRecordMap.put(result.getStationCode(), result.getStationCode());
                }
            }
        }
        //获取即将生成站位
        for (String stationCode : needStationCodeList) {
            if (!produceRecordMap.containsKey(stationCode)) {
                currentStationCode = stationCode;
                break;
            }
        }
        //如果循环必做站位是25_1,或者25_2,已经存在生产记录则不处理
        if (detectNode.getNodeCode().indexOf("_") >= 0
                && produceRecordMap.containsKey(detectNode.getNodeCode().split("_")[0])) {
            return;
        }
        if (currentStationCode.equals(detectNode.getNodeCode())
                && currentStationCode.equals(String.valueOf(passRequest.getStationNo()))) {
            isProduce = true;
        }
        //25站位处理
        if (detectNode.getNodeCode().indexOf("_")>= 0 && currentStationCode.equals(detectNode.getNodeCode().split("_")[0]) ){
            isProduce = true;
        }
        //尾站27站位处理
        if (currentStationCode.indexOf("L")>=0&&currentStationCode.equals(passRequest.getStationNo()+"L")){
            isProduce = true;
        }
        //写入过站结果
        PassResponse passResponse = new PassResponse();
        passResponse.setLineNo(passRequest.getLineNo());
        passResponse.setTelegramNo(passRequest.getTelegramNo());
        passResponse.setStationNo(passRequest.getStationNo());
        passResponse.setStationindex(passRequest.getStationindex());
        passResponse.setPartIdentifier(passRequest.getPartIdentifier());
        passResponse.setTypeNo(passRequest.getTypeNo());
        passResponse.setReturnCode(1);
        if (isProduce) {
            if (currentStationCode.indexOf("L")>=0){
                passResponse.setPartForStation(Integer.valueOf(currentStationCode.split("L")[0]));
            }else {
                passResponse.setPartForStation(Integer.valueOf(currentStationCode));
            }
        } else {
            if (currentStationCode.indexOf("L")>=0){
                passResponse.setNextForStation(Integer.valueOf(currentStationCode.split("L")[0]));
            }else {
                passResponse.setNextForStation(Integer.valueOf(currentStationCode));
            }
        }
        //存在NG产品记录
        if(judgeNGProduct(nodeResultList)){
            passResponse.setPartForStation(999);
        }
        //写入过站数据，DB511块
        stationExchangeService.writePassResponse(passResponse, detectNode);
        //写入指令数据
        db5409.setT11Result(1);
        stationExchangeService.writeDB5409(db5409, detectNode);
    }
    */
/**
     * 判断是否NG（不合格）产品生产记录
     *
     * @param nodeResultList
     * @return
     *//*

    public boolean judgeNGProduct(List<MesProductNodeResult> nodeResultList){
        AtomicBoolean result = new AtomicBoolean(false);
        if (CollectionUtils.isEmpty(nodeResultList)){
            return false;
        }
        nodeResultList.forEach(item->{
            if (NodeTestResultEnum.FAIL.getCode().equals(item.getTestResult())){
                result.set(true);
            }
        });
        return result.get();
    }

    */
/**
     * 根据partId查询产品大类对应检测站位列表
     *
     * @param partId
     * @return
     *//*

    public List<MesModelNodeRela> queryRelaListByPartId(String lineNumber, String partId) {
        List<MesModelNodeRela> relaList = null;
        if (partModelRelaMap.containsKey(partId+"_" +lineNumber)) {
            return partModelRelaMap.get(partId+"_" +lineNumber);
        }
        MesProdRecord mesProdRecord = prodRecordService.getMesProdRecordByPartId(partId);
        if (mesProdRecord != null){
            String modelCode = mesProdRecord.getModelCode();
            relaList = mesModelNodeRelaService.queryRelaListByModelCode(lineNumber, modelCode);
            if (CollectionUtils.isNotEmpty(relaList)){
                partModelRelaMap.put(partId+"_" +lineNumber, relaList);
            }
        }
        return relaList;
    }
    */
/**
     * 生产下线去掉缓存
     *
     * @param partId
     *//*

    public void offLineByPartId(String partId) {
        partModelRelaMap.remove(partId);
    }
}
*/
